#include "mch.h"

#include <string.h>
#include <sys/time.h>
#include <lwip/tcp.h>
#include "mch.h"

char * reply_str = "HTTP/1.0 200 OK\r\nContent-Type: text/html; charset=UTF-8\r\n\r\n";
#define TEST_HTTP_EN  0
#define TEST_TCP_EN   1


#if TEST_TCP_EN
static uint32_t conn_num = 0;
static uint32_t rx_num = 0;

void print_time(void)
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    printf("time = %d:%d \n", (u32_t)tv.tv_sec, (u32_t)tv.tv_usec);
}
#endif

static err_t  recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err)
{
  u16_t len = 0;
//  struct pbuf *pit;

  if (p)
    len = p->tot_len;

  //mch_printf("receive %d data from client\n", len);

  tcp_recved(pcb, len);

#if TEST_TCP_EN
  rx_num++;
  if( (rx_num&0xff) == 0 ){
    printf("got packet == %d\n", rx_num);
    print_time();
  }
#endif

  /*write back as echo*/
#if TEST_HTTP_EN
  tcp_write(pcb, reply_str, strlen(reply_str), 0);

/*
  pit =  p;
  while (pit)
  {
      pit = pit->next; 
  }   
*/
  tcp_close(pcb);
#endif  
  err = ERR_OK;
  return err;

}


static err_t  accept_cb(void *arg, struct tcp_pcb *npcb, err_t err)
{

  //mch_printf("Server:new connection from %s:%d\n", ipaddr_ntoa(&npcb->remote_ip), npcb->remote_port);  
  //tcp_accepted(npcb);

#if TEST_TCP_EN
  conn_num ++;
  if( (conn_num&0xfff) == 0 ){
    print_time();
    printf("accept connection == %d\n", conn_num);    
  }
#endif
  //tcp_setprio(npcb, TCP_PRIO_MIN);
  tcp_recv(npcb, recv_cb);
  /*Todo: asign this pcb to a cpu core*/

  err = ERR_OK;
  return err;
  
}


int server_init(struct ip_addr *ipaddr, u16_t port)
{
  struct tcp_pcb *pcb, *npcb;
  err_t err;

  pcb = tcp_new();
  if (!pcb)
  {
      mch_printf("tcp_new failed\n");
      return -1;
  }

  err = tcp_bind(pcb, ipaddr, port); 
  if (err != ERR_OK) 
  {
      mch_printf("tcp_bind failed\n");
      return -1;
  }

  npcb = tcp_listen(pcb);
  if (npcb == NULL)
  {
      mch_printf("tcp_listen failed\n");
      return -1;
  }

  tcp_accept(npcb, accept_cb);

  return 0;
}



